package org.store.dao;


import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.transaction.annotation.Transactional;
import org.store.domain.Payment;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

public class PaymentDao extends AbstractDao<Payment> {
    @Override
    public Payment getById(long id) throws DaoException {
        try {
            return jdbcTemplate.queryForObject("select payment_id, amount, info from payment where payment_id = ?", MAPPER, id);
        } catch (DataAccessException e) {
            throw new DaoException("Cannot get payment with id =" + id, e);
        }
    }

    @Override
    @Transactional
    public Payment save(Payment payment) throws DaoException {
        if (payment == null)
            throw new IllegalArgumentException("Payment cannot be null");
        try {
            long id = jdbcTemplate.queryForLong("insert into payment (amount, info) values(?,?) returning payment_id", payment.getAmount(), payment.getInfo());
            payment.setId(id);
            return payment;
        } catch (DataAccessException e) {
            throw new DaoException("Cannot save payment with id = " + payment.getId(), e);
        }
    }

    @Override
    public boolean delete(Payment payment) throws DaoException {
        try {
            int updated = jdbcTemplate.update("delete from payment where payment_id = ?", payment.getId());
            return updated > 0;
        } catch (DataAccessException e) {
            throw new DaoException("Cannot delete payment with id = " + payment.getId(), e);
        }
    }

    @Override
    public Payment saveOrUpdate(Payment payment) throws DaoException {
        if (payment.getId() == null) {
            return save(payment);
        }
        try {
            jdbcTemplate.update("update payment SET amount = ?, info = ? where payment_id = ?", payment.getAmount(),
                    payment.getInfo(), payment.getId());
            return payment;
        } catch (DataAccessException e) {
            throw new DaoException("Cannot update payment with id = " + payment.getId(), e);
        }
    }

    @Override
    @Transactional
    public List<Payment> saveAll(final List<Payment> payments) throws DaoException {
        if (payments == null)
            throw new IllegalArgumentException("Array cannot be null");
        for (Payment payment : payments) {
            save(payment);
        }
        return payments;
    }

    @Override
    public boolean isExists(long id) throws DaoException {
        try {
            return jdbcTemplate.queryForLong("select count(*) from payment where payment_id = ?", id) > 0;
        } catch (DataAccessException e) {
            throw new DaoException("Cannot get payment with id = " + id, e);
        }
    }

    private static final RowMapper<Payment> MAPPER = new RowMapper<Payment>() {
        public Payment mapRow(ResultSet rs, int rowNum) throws SQLException {
            Payment payment = new Payment(rs.getInt("amount"), rs.getString("info"));
            payment.setId(rs.getLong("payment_id"));
            return payment;
        }
    };
}
